/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    monitor.h
 *  @brief   monitor header file
 *  @version v1.0
 *  @date    03. Apr. 2023
 ****************************************************************/

#ifndef __MONITOR_H__
#define __MONITOR_H__

#include <stdint.h>
#include "io.h"
#include "bits.h"
#include "mem_map_table.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef void (*mnt_irq_callback)(void *ptr);

#define MNT_BASE_ADDR                     MEM_MAP_MONITOR_BASE_ADDR

#define MNT_CFG_GLB_REG                   MNT_BASE_ADDR
#define MNT_CFG_ABN_SEL_POS               8
#define MNT_CFG_ABN_ARC_SEL_POS           4
#define MNT_CFG_SMP_SEL_POS               1
#define MNT_CFG_MON_EN_POS                0
#define MNT_CFG_ABN_SEL_LEN               18
#define MNT_CFG_ABN_ARC_SEL_LEN           3
#define MNT_CFG_SMP_SEL_LEN               1
#define MNT_CFG_MON_EN_LEN                1

#define MNT_CFG_START_REG                 (MNT_BASE_ADDR + 0x4)
#define MNT_CFG_SEL_DONE_POS              24
#define MNT_CFG_SMP_START_POS             0
#define MNT_CFG_SEL_DONE_LEN              1
#define MNT_CFG_SMP_START_LEN             18

#define MNT_CFG_END_REG                   (MNT_BASE_ADDR+ 0x8)
#define MNT_CFG_SMP_END_POS               0
#define MNT_CFG_SMP_END_LEN               18

#define MNT_CFG_WDMA_REG                  (MNT_BASE_ADDR + 0xC)
#define MNT_CFG_LP_EN_POS                 16
#define MNT_CFG_TIMEOUT_POS               0
#define MNT_CFG_LP_EN_LEN                 1
#define MNT_CFG_TIMEOUT_LEN               16

#define MNT_CFG_CH_REG(ch)                (MNT_BASE_ADDR + 0x10 + ch*4)
#define MNT_CFG_ZCP_SMP_NUM_POS           28
#define MNT_CFG_ABN_SMP_NUM_POS           16
#define MNT_CFG_SMP_MODE_POS              14
#define MNT_CFG_BUF_SIZE_POS              0  /* 4 Bytes Align */
#define MNT_CFG_ZCP_SMP_NUM_LEN           4
#define MNT_CFG_ABN_SMP_NUM_LEN           12
#define MNT_CFG_SMP_MODE_LEN              2
#define MNT_CFG_BUF_SIZE_LEN              14

#define MNT_CFG_PING_ADDR_REG(ch)         (MNT_BASE_ADDR + 0x60 + ch*4) /* 16 Bytes Align */
#define MNT_CFG_PANG_ADDR_REG(ch)         (MNT_BASE_ADDR + 0xB0 + ch*4) /* 16 Bytes Align */

#define MNT_CFG_ZCP_SEL_REG(ch)           (MNT_BASE_ADDR + 0x100 + ch*4)
#define MNT_CFG_ZCP_SEL_POS               0
#define MNT_CFG_ZCP_SEL_LEN               18

#define MNT_CFG_ARC_SEL_REG(ch)           (MNT_BASE_ADDR + 0x160 + ch*4)
#define MNT_CFG_ARC_SEL_POS               0
#define MNT_CFG_ARC_SEL_LEN               3

#define MNT_IMC_REG(reg)                  (MNT_BASE_ADDR + 0x200 + reg*4)
#define MNT_ICR_REG(reg)                  (MNT_BASE_ADDR + 0x240 + reg*4)
#define MNT_ISR_REG(reg)                  (MNT_BASE_ADDR + 0x280 + reg*4)
#define MNT_MIS_REG(reg)                  (MNT_BASE_ADDR + 0x2C0 + reg*4)
#define MNT_CH_INTR_BIT(ch)               BIT(ch)

#define MNT_DMA_WR_STAT0_REG(ch)          (MNT_BASE_ADDR + 0x300 + ch*4)

#define MNT_DMA_WR_STAT1_REG(ch)          (MNT_BASE_ADDR + 0x350 + ch*4)
#define MNT_DMA_WR_BYTES_POS              0
#define MNT_DMA_WR_BYTES_LEN              16

#define MNT_PING_STAT_REG(ch)             (MNT_BASE_ADDR + 0x3A0 + ch*4)
#define MNT_PANG_STAT_REG(ch)             (MNT_BASE_ADDR + 0x3F0 + ch*4)

#define MNT_DMA_ACTIVE_REG                (MNT_BASE_ADDR + 0x440)
#define MNT_DMA_ACTIVE_POS                0
#define MNT_DMA_ACTIVE_LEN                18

#define MNT_CFG_WAV_EN_REG                (MNT_BASE_ADDR + 0x800)
#define MNT_CFG_WAV_EN_POS                0
#define MNT_CFG_WAV_EN_LEN                2

#define MNT_CFG_HIGH_BX_REG(x)            (MNT_BASE_ADDR + 0x804 + x*4)
#define MNT_CFG_HIGH_BX_POS               0
#define MNT_CFG_HIGH_BX_LEN               16

#define MNT_CFG_LOW_BX_REG(x)             (MNT_BASE_ADDR + 0x824 + x*4)
#define MNT_CFG_LOW_BX_POS                0
#define MNT_CFG_LOW_BX_LEN                16

#define MNT_DEC_SOUR_SEL_REG              (MNT_BASE_ADDR + 0x844)
#define MNT_DEC_SOUR_SEL_POS              0
#define MNT_DEC_SOUR_SEL_LEN              2

#define MNT_ARC_HALF_WAV_NUM_REG          (MNT_BASE_ADDR + 0x848)
#define MNT_ARC_HALF_WAV_NUM_POS          0
#define MNT_ARC_HALF_WAV_NUM_LEN          12

#define MNT_ARC_EN_PEAK_REG               (MNT_BASE_ADDR + 0x84C)
#define MNT_ARC_EN_PEAK_POS               0
#define MNT_ARC_EN_PEAK_LEN               1

#define MNT_ARC_EN_AVERAGE_REG            (MNT_BASE_ADDR + 0x850)
#define MNT_ARC_EN_AVERAGE_POS            0
#define MNT_ARC_EN_AVERAGE_LEN            1

#define MNT_ARC_PARTHR_REG                (MNT_BASE_ADDR + 0x854)
#define MNT_ARC_PARTHR_POS                0
#define MNT_ARC_PARTHR_LEN                8

#define MNT_MAX_BIT_REG                   (MNT_BASE_ADDR + 0x858)
#define MNT_MAX_BIT_POS                   0
#define MNT_MAX_BIT_LEN                   5

#define MNT_CFG_ADC_MUX_REG               (MNT_BASE_ADDR + 0x85C)
#define MNT_CFG_ADC_MUX_POS               0
#define MNT_CFG_ADC_MUX_LEN               1

#define MNT_CFG_ARC_ALL_DONE_REG          (MNT_BASE_ADDR + 0x860)
#define MNT_CFG_ARC_ALL_DONE_POS          0
#define MNT_CFG_ARC_ALL_DONE_LEN          1

#define MNT_IA_RESULT_X_REG(x)            (MNT_BASE_ADDR + 0x864 + x*4)
#define MNT_IB_RESULT_X_REG(x)            (MNT_BASE_ADDR + 0x874 + x*4)
#define MNT_IC_RESULT_X_REG(x)            (MNT_BASE_ADDR + 0x884 + x*4)

#define MNT_RESULT_PTR_REG                (MNT_BASE_ADDR + 0x894)
#define MNT_IA_PTR_POS                    0
#define MNT_IB_PTR_POS                    8
#define MNT_IC_PTR_POS                    16
#define MNT_IA_PTR_LEN                    7
#define MNT_IB_PTR_LEN                    7
#define MNT_IC_PTR_LEN                    7

#define MNT_RESULT_LOCK_REG               (MNT_BASE_ADDR + 0x89C)
#define MNT_IA_RD_POS                     0
#define MNT_IB_RD_POS                     1
#define MNT_IC_RD_POS                     2
#define MNT_IA_RD_LEN                     1
#define MNT_IB_RD_LEN                     1
#define MNT_IC_RD_LEN                     1

#define MNT_MAX_CHANNEL_NUM               18

#define MNT_SMP_DMEM_BASE_ADDR            (DMEM_BASE + DMEM_SIZE)
#define MNT_SMP_FLASH_BASE_ADDR           0x44000
#define MNT_SMP_MAX_BUF_SIZE              0x800
#define MNT_PING_BUF_OFFSET(ch, size)     (size*2*ch)
#define MNT_PANG_BUF_OFFSET(ch, size)     (MNT_PING_BUF_OFFSET(ch, size) + size)
#define MNT_PING_BUF_DMEM_ADDR(ch, size)  (MNT_SMP_DMEM_BASE_ADDR + MNT_PING_BUF_OFFSET(ch, size))
#define MNT_PANG_BUF_DMEM_ADDR(ch, size)  (MNT_SMP_DMEM_BASE_ADDR + MNT_PANG_BUF_OFFSET(ch, size))
#define MNT_PING_BUF_FLASH_ADDR(ch, size) (MNT_SMP_FLASH_BASE_ADDR + MNT_PING_BUF_OFFSET(ch, size))
#define MNT_PANG_BUF_FLASH_ADDR(ch, size) (MNT_SMP_FLASH_BASE_ADDR + MNT_PANG_BUF_OFFSET(ch, size))

enum mnt_imc_reg {
	IMC_SINGLE_DONE,
	IMC_CONT_PINGDONE,
	IMC_CONT_PANGDONE,
	IMC_ZCP_PINGDONE,
	IMC_ZCP_PANGDONE,
	IMC_ZCP_PINGABORT,
	IMC_ZCP_PANGABORT,
	IMC_ABN_DONE,
	IMC_HRESP,
	IMC_TIMEOUT,
	IMC_ARC,
	MNT_IMC_MAX,
};

enum mnt_icr_reg {
	ICR_SINGLE_DONE,
	ICR_CONT_PINGDONE,
	ICR_CONT_PANGDONE,
	ICR_ZCP_PINGDONE,
	ICR_ZCP_PANGDONE,
	ICR_ZCP_PINGABORT,
	ICR_ZCP_PANGABORT,
	ICR_ABN_DONE,
	ICR_HRESP,
	ICR_TIMEOUT,
	ICR_ARC,
};

enum mnt_isr_reg {
	ISR_SINGLE_DONE,
	ISR_CONT_PINGDONE,
	ISR_CONT_PANGDONE,
	ISR_ZCP_PINGDONE,
	ISR_ZCP_PANGDONE,
	ISR_ZCP_PINGABORT,
	ISR_ZCP_PANGABORT,
	ISR_ABN_DONE,
	ISR_HRESP,
	ISR_TIMEOUT,
	ISR_ARC,
};

enum mnt_mis_reg {
	MIS_SINGLE_DONE,
	MIS_CONT_PINGDONE,
	MIS_CONT_PANGDONE,
	MIS_ZCP_PINGDONE,
	MIS_ZCP_PANGDONE,
	MIS_ZCP_PINGABORT,
	MIS_ZCP_PANGABORT,
	MIS_ABN_DONE,
	MIS_HRESP,
	MIS_TIMEOUT,
	MIS_ARC,
};

enum mnt_en {
	MONITOR_DIS,
	MONITOR_EN,
};

enum wdma_lp_en {
	WDMA_LP_DIS,
	WDMA_LP_EN,
};

enum smp_src_sel {
	SMP_SEL_MONITOR,
	SMP_SEL_HAC,
};

enum smp_mode {
	SMP_SINGLE,
	SMP_CONT,
	SMP_ZCP,
	SMP_ABN,
};

enum smp_mnt_channel {
	SMP_MNT_CHANNEL_UA,
	SMP_MNT_CHANNEL_UB,
	SMP_MNT_CHANNEL_UC,
	SMP_MNT_CHANNEL_IA,
	SMP_MNT_CHANNEL_IB,
	SMP_MNT_CHANNEL_IC,
	SMP_MNT_CHANNEL_IN,
	SMP_MNT_CHANNEL_IL,
	SMP_MNT_CHANNEL_ARC_IA,
	SMP_MNT_CHANNEL_ARC_IB,
	SMP_MNT_CHANNEL_ARC_IC,
	SMP_MNT_CHANNEL_CD_IA,
	SMP_MNT_CHANNEL_CD_IB,
	SMP_MNT_CHANNEL_CD_IC,
};

enum smp_hac_channel {
	SMP_HAC_CHANNEL_UA,
	SMP_HAC_CHANNEL_UB,
	SMP_HAC_CHANNEL_UC,
	SMP_HAC_CHANNEL_IA,
	SMP_HAC_CHANNEL_IB,
	SMP_HAC_CHANNEL_IC,
	SMP_HAC_CHANNEL_IN,
	SMP_HAC_CHANNEL_FIL,
	SMP_HAC_CHANNEL_IT,
	SMP_HAC_CHANNEL_UT,
	SMP_HAC_CHANNEL_FUA,
	SMP_HAC_CHANNEL_FUB,
	SMP_HAC_CHANNEL_FUC,
	SMP_HAC_CHANNEL_FIA,
	SMP_HAC_CHANNEL_FIB,
	SMP_HAC_CHANNEL_FIC,
	SMP_HAC_CHANNEL_FIN,
	SMP_HAC_CHANNEL_FIT,
};

enum zcp_int_sel {
	ZCP_INT_UA,
	ZCP_INT_UB,
	ZCP_INT_UC,
	ZCP_INT_IA,
	ZCP_INT_IB,
	ZCP_INT_IC,
	ZCP_INT_IN,
	ZCP_INT_IL,
	ZCP_INT_IT,
	ZCN_INT_UA,
	ZCN_INT_UB,
	ZCN_INT_UC,
	ZCN_INT_IA,
	ZCN_INT_IB,
	ZCN_INT_IC,
	ZCN_INT_IN,
	ZCN_INT_IL,
	ZCN_INT_IT,
};

enum arc_int_sel {
	ARC_INT_IA,
	ARC_INT_IB,
	ARC_INT_IC,
};

enum abn_int_sel {
	ABN_INT_SAG_UC,
	ABN_INT_SAG_UB,
	ABN_INT_SAG_UA,
	ABN_INT_OVP_UC,
	ABN_INT_OVP_UB,
	ABN_INT_OVP_UA,
	ABN_INT_LOSV_UC,
	ABN_INT_LOSV_UB,
	ABN_INT_LOSV_UA,
	ABN_INT_SC_IC,
	ABN_INT_SC_IB,
	ABN_INT_SC_IA,
	ABN_INT_OVF_ILRMS,
	ABN_INT_OVF_IC,
	ABN_INT_OVF_IB,
	ABN_INT_OVF_IA,
	ABN_INT_UPHSQ_ERR,
	ABN_INT_ZC_OT,
};

enum arc_adc_mux {
	ARC_SAR_ADC_MUX,
	ARC_SD_ADC_MUX,
};

enum arc_wavlet_en {
	ARC_WAVLET_Y1_N23,
	ARC_WAVLET_Y1N23,
	ARC_WAVLET_Y12_N3,
	ARC_WAVLET_Y123,
};

enum arc_high_bx {
	ARC_HIGH_B0,
	ARC_HIGH_B1,
	ARC_HIGH_B2,
	ARC_HIGH_B3,
	ARC_HIGH_B4,
	ARC_HIGH_B5,
	ARC_HIGH_B6,
	ARC_HIGH_B7,
};

enum arc_low_bx {
	ARC_LOW_B0,
	ARC_LOW_B1,
	ARC_LOW_B2,
	ARC_LOW_B3,
	ARC_LOW_B4,
	ARC_LOW_B5,
	ARC_LOW_B6,
	ARC_LOW_B7,
};

enum arc_dec_sour_sel {
	ARC_DEC_SOUR_CD1_SEL,
	ARC_DEC_SOUR_CD2_SEL,
	ARC_DEC_SOUR_CD3_SEL,
};

enum arc_enable {
	ARC_DIS,
	ARC_EN,
};

enum arc_results_phase {
	ARC_RESULTS_IA,
	ARC_RESULTS_IB,
	ARC_RESULTS_IC,
};

enum arc_results_id {
	ARC_RESULTS_0,
	ARC_RESULTS_1,
	ARC_RESULTS_2,
	ARC_RESULTS_3,
	ARC_RESULTS_MAX,
};

typedef struct {
	uint32_t ch_list;
	enum smp_src_sel smp_src;
	uint32_t ping_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t buf_size[MNT_MAX_CHANNEL_NUM];
} smp_single_para_t;

typedef struct {
	uint32_t ch_list;
	enum smp_src_sel smp_src;
	uint32_t ping_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t pang_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t buf_size[MNT_MAX_CHANNEL_NUM];
} smp_cont_para_t;

typedef struct {
	uint32_t ch_list;
	enum smp_src_sel smp_src;
	uint32_t ping_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t pang_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t buf_size[MNT_MAX_CHANNEL_NUM];
	uint32_t zcp_smp_num[MNT_MAX_CHANNEL_NUM];
	enum zcp_int_sel zcp_int[MNT_MAX_CHANNEL_NUM];
} smp_zcp_para_t;

typedef struct {
	uint32_t ch_list;
	enum smp_src_sel smp_src;
	uint32_t ping_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t pang_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t buf_size[MNT_MAX_CHANNEL_NUM];
	uint32_t zcp_smp_num[MNT_MAX_CHANNEL_NUM];
	enum arc_int_sel zcp_arc_int[MNT_MAX_CHANNEL_NUM];
} smp_zcp_arc_para_t;

typedef struct {
	uint32_t ch_list;
	enum smp_src_sel smp_src;
	uint32_t ping_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t buf_size[MNT_MAX_CHANNEL_NUM];
	uint32_t abn_smp_num[MNT_MAX_CHANNEL_NUM];
	uint32_t abn_int[MNT_MAX_CHANNEL_NUM];
} smp_abn_para_t;

typedef struct {
	uint32_t ch_list;
	enum smp_src_sel smp_src;
	uint32_t ping_addr[MNT_MAX_CHANNEL_NUM];
	uint32_t buf_size[MNT_MAX_CHANNEL_NUM];
	uint32_t abn_smp_num[MNT_MAX_CHANNEL_NUM];
	uint32_t abn_arc_int[MNT_MAX_CHANNEL_NUM];
} smp_abn_arc_para_t;

typedef struct {
	enum arc_adc_mux mux;
	enum arc_wavlet_en wav_en;
} arc_basic_cfg_t;

typedef struct {
	enum arc_high_bx high_bx;
	int16_t high_val;
	enum arc_low_bx low_bx;
	int16_t low_val;
} arc_filter_para_t;

typedef struct {
	enum arc_dec_sour_sel dec_sour_sel;
	uint8_t half_wave_num;
	enum arc_enable en_peak;
	enum arc_enable en_average;
	uint8_t par_thr;
	uint8_t max_bit;
} arc_error_check_para_t;

void mnt_smp_configure(uint32_t buf_size, enum smp_src_sel sel);
void mnt_smp_configure_get(uint32_t *buf_size, enum smp_src_sel *sel);
void mnt_smp_single_start(smp_single_para_t *para);
void mnt_smp_cont_start(smp_cont_para_t *para);
void mnt_smp_cont_stop(uint32_t ch_list);
void mnt_smp_zcp_start(smp_zcp_para_t *para);
void mnt_smp_zcp_arc_start(smp_zcp_arc_para_t *para);
void mnt_smp_zcp_stop(uint32_t ch_list);
void mnt_smp_abn_start(smp_abn_para_t *para);
void mnt_smp_abn_arc_start(smp_abn_arc_para_t *para);
void mnt_cfg_arc_para(arc_basic_cfg_t *arc_basic, arc_filter_para_t *arc_filter, arc_error_check_para_t *arc_error_check);
void mnt_arc_result_cb_register(mnt_irq_callback cb);
void monitor_init(void);

#ifdef __cplusplus
}
#endif

#endif /* __MONITOR_H__ */

